﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Publications.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   Stores the name of the object, object propery and corresponding variable name
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.Saf.Engine.DynamicVariables
{
    using System.Collections.Generic;

    /// <summary>
    /// Stores the name of the object, object propery and corresponding variable name 
    /// </summary>
    public class ObjectPublication
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectPublication"/> class.
        /// </summary>
        /// <param name="variableName">
        /// Name of the variable.
        /// </param>
        /// <param name="objectPropertyName">
        /// Name of the object property.
        /// </param>
        /// <param name="objectPropertyValue">
        /// The object property value.
        /// </param>
        /// <param name="instance">
        /// The instance.
        /// </param>
        public ObjectPublication(
            string variableName, string objectPropertyName, object objectPropertyValue, object instance)
        {
            this.VariableName = variableName;
            this.PropertyName = objectPropertyName;
            this.PropertyValue = objectPropertyValue;
            this.Instance = instance;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the Instance of the object that is publishing the the variable
        /// </summary>
        public object Instance { get; set; }

        /// <summary>
        /// Gets or sets the name of the object property that is publishing the variable.
        /// </summary>
        public string PropertyName { get; set; }

        /// <summary>
        /// Gets or sets the value of the published variable.
        /// </summary>
        public object PropertyValue { get; set; }

        /// <summary>
        /// Gets or sets the name of the variable to be published.
        /// </summary>
        public string VariableName { get; set; }

        #endregion
    }

    /// <summary>
    /// Stores all the publications for a specific object
    /// </summary>
    public class ObjectPublications : List<ObjectPublication>
    {
    }

    /// <summary>
    /// Collection of all dynamic assignments created by each object
    /// </summary>
    public class Publications
    {
        #region Constants and Fields

        /// <summary>
        /// Stores the variables publications for each object (object centric).
        /// <remarks>
        /// It main contain more than one publication for the same variable (if more than one object are publishing the same variable)
        /// </remarks>
        /// </summary>
        private Dictionary<string, ObjectPublications> publications = new Dictionary<string, ObjectPublications>();

        #endregion

        #region Properties

        /// <summary>
        /// Gets the objects.
        /// </summary>
        /// <value>The objects.</value>
        public IEnumerable<string> Objects
        {
            get
            {
                return this.publications.Keys;
            }
        }

        #endregion

        #region Indexers

        /// <summary>
        /// Gets the <see cref="ObjectPublications"/> with the specified object name.
        /// </summary>
        /// <value></value>
        public ObjectPublications this[string objectName]
        {
            get
            {
                return this.publications[objectName];
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Adds the object publication.
        /// </summary>
        /// <param name="objectName">
        /// Name of the object.
        /// </param>
        /// <param name="publication">
        /// The publication.
        /// </param>
        public void AddObjectPublication(string objectName, ObjectPublication publication)
        {
            ObjectPublications objectAssignments;

            if (this.publications.ContainsKey(objectName))
            {
                objectAssignments = this.publications[objectName];
            }
            else
            {
                objectAssignments = new ObjectPublications();
                this.publications.Add(objectName, objectAssignments);
            }

            objectAssignments.Add(publication);
        }

        /// <summary>
        /// Clears all the object instances.
        /// </summary>
        public void ClearObjectInstances()
        {
            foreach (ObjectPublications publications in this.publications.Values)
            {
                foreach (ObjectPublication publication in publications)
                {
                    publication.Instance = null;
                }
            }
        }

        /// <summary>
        /// Registers the object instance.
        /// </summary>
        /// <param name="objectName">
        /// Name of the object.
        /// </param>
        /// <param name="instance">
        /// The instance.
        /// </param>
        public void RegisterObjectInstance(string objectName, object instance)
        {
            if (this.publications.ContainsKey(objectName))
            {
                foreach (ObjectPublication publication in this.publications[objectName])
                {
                    publication.Instance = instance;
                }
            }
        }

        #endregion
    }
}